# -*- coding=UTF-8 -*-

from pymysqlreplication import BinLogStreamReader
from pymysqlreplication.row_event import (DeleteRowsEvent,UpdateRowsEvent,WriteRowsEvent,)
from pymysqlreplication.event import QueryEvent
import logging as log
import json
import argparse

def dump_write_event(binlog_event):
    event_json = {}
    for row in binlog_event.rows:
        schema = binlog_event.schema
        table = binlog_event.table
        event_json['values'] = dict(row['values'].items())
        event_json['event'] = 'insert'
        event_json['schema'] = schema
        event_json['table'] = table
        event_json['log_post'] = binlog_event.packet.log_pos
        log.info(json.dumps(event_json))

def dump_delete_event(binlog_event):
    event_json = {}
    for row in binlog_event.rows:
        schema = binlog_event.schema
        table = binlog_event.table
        event_json['values'] = dict(row['values'].items())
        event_json['event'] = 'delete'
        event_json['schema'] = schema
        event_json['table'] = table
        event_json['pk'] = binlog_event.primary_key
        event_json['log_post'] = binlog_event.packet.log_pos
        log.info(json.dumps(event_json))

def dump_update_event(binlog_event):
    event_json = {}
    for row in binlog_event.rows:
        schema = binlog_event.schema
        table = binlog_event.table
        event_json['event'] = 'update'
        event_json['schema'] = schema
        event_json['table'] = table
        event_json['log_post'] = binlog_event.packet.log_pos
        event_json['before_values'] = dict(row['before_values'].items())
        event_json['after_values'] = dict(row['after_values'].items())
        log.info(json.dumps(event_json))

def dump_query_event(binlog_event):
    event_json = {}
    event_json['event'] = 'query'
    schema = binlog_event.schema
    query = binlog_event.query
    event_json['schema'] = schema
    event_json['log_post'] = binlog_event.packet.log_pos
    event_json['query'] = query
    log.info(json.dumps(event_json))

def process_binlog(mysql_settings, stream):
    for binlog_event in stream:
        if isinstance(binlog_event, WriteRowsEvent):
            dump_write_event(binlog_event)
        elif isinstance(binlog_event, DeleteRowsEvent):
            dump_delete_event(binlog_event)
        elif isinstance(binlog_event, UpdateRowsEvent):
            dump_update_event(binlog_event)
        elif isinstance(binlog_event, QueryEvent):
            dump_query_event(binlog_event)
    stream.close()

def parse_params():
    parser = argparse.ArgumentParser(description='')
    parser.add_argument('--host', '-H', help='')
    parser.add_argument('--port', '-P', help='', default=3306, type=int)
    parser.add_argument('--user', '-u', help='')
    parser.add_argument('--passwd', '-p', help='')
    parser.add_argument('--file', '-f', help='', default=None)
    parser.add_argument('--pos', '-s', help='', default=4, type=int)
    return parser.parse_args()

def main():
    log.basicConfig(level=log.INFO,
                format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                datefmt='%a, %d %b %Y %H:%M:%S',
                filename='test.log',
                filemode='a')
    args = parse_params()
    host = args.host
    port = args.port
    user = args.user
    passwd = args.passwd
    log_pos = args.pos
    log_file = args.file
    mysql_settings = {'host': host, 'port': port, 'user': user, 'passwd': passwd}
    stream = BinLogStreamReader(connection_settings = mysql_settings, server_id=100, log_pos=log_pos, blocking=True, log_file=log_file)
    process_binlog(mysql_settings, stream)

if __name__=='__main__':
    main()
